package com.jumi.microservice.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jumi.microservice.common.base.dto.BasePageResponse;
import com.jumi.microservice.common.base.dto.ResponseResult;
import com.jumi.microservice.common.utils.ResultGenerator;
import com.jumi.microservice.constant.ExceptionEnum;
import com.jumi.microservice.constant.StatusEnum;
import com.jumi.microservice.domain.*;
import com.jumi.microservice.domain.dto.ArticleDTO;
import com.jumi.microservice.domain.vo.ArticleOP;
import com.jumi.microservice.domain.vo.ArticleQuery;
import com.jumi.microservice.domain.vo.ArticleVO;
import com.jumi.microservice.mapper.ArticleClassMapper;
import com.jumi.microservice.service.ArticleService;
import com.jumi.microservice.service.LogService;
import com.jumi.microservice.utils.LogObjectCopyUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@Api(tags = "文章管理相关接口")
@RequestMapping("/auth/Article")
public class ArticleController {

    @Autowired
    private ArticleService articleService;
    @Autowired
    private ArticleClassMapper articleClassMapper;
    @Autowired
    private LogService logService;

    @ApiOperation(value = "新增文章", notes = "新增一条文章表数据")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "分类id", value = "acid"),
            @ApiImplicitParam(name = "标题", value = "articleTitle"),
            @ApiImplicitParam(name = "内容", value = "articleContent"),
            @ApiImplicitParam(name = "排序", value = "sort"),
    })
    @PostMapping("/add")
    public ResponseResult add(@Validated @RequestBody ArticleOP op, HttpServletRequest request){
        articleService.insert(op,request);
        return ResultGenerator.genSuccessResult();
    }

    @ApiOperation(value = "编辑文章", notes = "编辑一条文章表数据")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "id"),
            @ApiImplicitParam(name = "分类id", value = "acid"),
            @ApiImplicitParam(name = "标题", value = "articleTitle"),
            @ApiImplicitParam(name = "内容", value = "articleContent"),
            @ApiImplicitParam(name = "排序", value = "sort"),
    })
    @PutMapping("/update")
    public ResponseResult update(@Validated @RequestBody ArticleOP op,HttpServletRequest request){
        articleService.update(op,request);
        return ResultGenerator.genSuccessResult();
    }

    @ApiOperation(value = "删除文章数据", notes = "删除指定ID文章表数据")
    @ApiImplicitParam(name = "id", value = "ID")
    @DeleteMapping("/delete")
    public ResponseResult delete(Long id, HttpServletRequest request){
        articleService.delete(id,request);
        return ResultGenerator.genSuccessResult();
    }

    @ApiOperation(value = "文章状态更改", notes = "指定文章状态修改")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "id", value = "ID"),
        @ApiImplicitParam(name = "状态，1启用，0.禁用", value = "status")
    })
    @PutMapping("/status")
    public ResponseResult status(Long id,Integer status,HttpServletRequest request){
        articleService.status(id,status,request);
        return ResultGenerator.genSuccessResult();
    }

    @ApiOperation(value = "分页查询", notes = "获取文章表分页列表数据")
    @GetMapping("/list")
    public BasePageResponse list(
            @RequestParam(defaultValue = "0") Integer page,
            @RequestParam(defaultValue = "0") Integer size,
            ArticleQuery articleQuery){
        LambdaQueryWrapper<Article> wrapper = Wrappers.lambdaQuery();
        wrapper.like(StringUtils.isNotEmpty(articleQuery.getArticleTitle()),Article::getArticleTitle,articleQuery.getArticleTitle());
        wrapper.eq(articleQuery.getStatus()!=null,Article::getStatus,articleQuery.getStatus());
        wrapper.eq(articleQuery.getAcid()!=null,Article::getAcid,articleQuery.getAcid());
        wrapper.eq(Article::getIsDel,0);
        wrapper.orderByDesc(Article::getId);
        IPage<Article> pageInfo = articleService.page(new Page<>(page, size), wrapper);

        for (Article article:pageInfo.getRecords()) {
            ArticleClass articleClass = articleClassMapper.selectById(article.getAcid());
            article.setAcName(articleClass.getAcName());
            if(articleClass.getAcParentId() > 0){
                ArticleClass articClassArray = articleClassMapper.selectById(articleClass.getAcParentId());
                article.setAcParentName(articClassArray.getAcName()+"->"+articleClass.getAcName());
            }
        }
        return ResultGenerator.genSuccessResultPage(pos2Vos(pageInfo.getRecords()), pageInfo.getTotal());
    }

    @ApiOperation(value = "查询数据", notes = "获取指定ID文章表数据")
    @ApiImplicitParam(name = "id", value = "ID")
    @GetMapping("/detail")
    public ResponseResult<ArticleVO> detail(Long id){
        ArticleDTO articleDTO = articleService.selectId(id);
        ArticleClass articleClass = articleClassMapper.selectById(articleDTO.getAcid());
        if(articleClass.getAcParentId() > 0){
            ArticleClass articClassArray = articleClassMapper.selectById(articleClass.getAcParentId());
            articleDTO.setAcName(articClassArray.getAcName()+"->"+articleClass.getAcName());
        }

        return ResultGenerator.genSuccessResult(dto2Vo(articleDTO));
    }


    @ApiOperation(value = "文章分类", notes = "文章分类详情")
    @ApiImplicitParam(name = "status", value = "状态，1启用，0.禁用")
    @GetMapping("/ArticleClassArray")
    public ResponseResult<List<ArticleClass>> ArticleClassArray(Integer status){
        List<ArticleClass> list = articleClassMapper.selectList(
                Wrappers.<ArticleClass>lambdaQuery()
                .select(ArticleClass::getAcid,ArticleClass::getAcName,ArticleClass::getAcParentId)
                .eq(status!=null, ArticleClass::getStatus, status)
                .gt(ArticleClass::getAcParentId,0)
                .eq(ArticleClass::getIsDel,0)
                .orderByDesc(ArticleClass::getUpdateTime)
        );
        for (ArticleClass articleClass : list) {
            if(articleClass.getAcParentId() > 0){
                ArticleClass articClassArray = articleClassMapper.selectById(articleClass.getAcParentId());
                articleClass.setAcParentName(articClassArray.getAcName()+"->"+articleClass.getAcName());
            }
        }

        return ResultGenerator.genSuccessResult(list);
    }

    @ApiOperation(value = "模块操作日志查询", notes = "模块操作日志查询分页列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "当前页码"),
            @ApiImplicitParam(name = "size", value = "分页大小"),
    })
    @GetMapping("/listLog")
    public BasePageResponse listLog(
            @RequestParam(defaultValue = "1") Integer page,
            @RequestParam(defaultValue = "0") Integer size,
            OperateLogQuery logQuery) {

        Page<Log> list = logService.listOperateLogs(logQuery);
        return ResultGenerator.genSuccessResultPage(LogObjectCopyUtil.convertOperateLogDoList2VoList(list.getRecords()), list.getTotal());
    }

    /**
     * 部门对象转换 dto->vo
     *
     * @param dto 部门dto
     * @return 部门vo
     */
    private ArticleVO dto2Vo(ArticleDTO dto) {
        ArticleVO vo = null;
        try {
            vo = dto.clone(ArticleVO.class);
        } catch (Exception e) {
            ExceptionEnum.FAIL_CHANGE.newException();
        }
        return vo;
    }

    /**
     * 部门DO对象转换 do->vo
     *
     * @param articles 部门do集合
     * @return 部门VO集合
     */
    private List<ArticleVO> pos2Vos(List<Article> articles) {
        List<ArticleVO> pos = articles.stream().map(p -> {
            ArticleVO vo = null;
            try {
                vo = p.clone(ArticleVO.class);
            } catch (Exception e) {
                ExceptionEnum.FAIL_CHANGE.newException();
            }
            return vo;
        }).collect(Collectors.toList());
        return pos;
    }

    /**
     * 分类VO对象转换 vo->dto
     * @param vo
     * @return
     */
    private ArticleDTO vo2Dto(ArticleVO vo) {
        ArticleDTO dto = null;
        try {
            dto = vo.clone(ArticleDTO.class);
        } catch (Exception e) {
            ExceptionEnum.FAIL_CHANGE.newException();
        }
        return dto;
    }
}
